import { SYSTEM_CODE } from '@/constant/common/common'
import WSResult from '@/utils/ws/WSResult'
import { HEART_BEAT_TYPE } from './constant'

const createWS = () => {

  if (!window.WebSocket) {
    alert('您的浏览器不支持使用WebSocket，请更换浏览器，否则部分功能无法正常使用')
    return []
  }

  let reconnectFlag = false     // 是否在重新连接，避免重复尝试：onerror方法可能重复触发，而此时已经在尝试重新连接
  let timeoutHandle = null      // 超时处理定时器
  let reconnectHandle = null    // 重连定时器
  let timeout = 30000           // 超时重连间隔
  let timeoutFlag = true        // 是否超时标识
  let maxReconnectNum = 10      // 重连次数
  let actReconnectNum = 0       // 实际重连次数
  let ws = null                 // ws的连接实例
  let heartBeat = {
    interval: 30000,
    timer: null,
    start: function() {
      // 如果有定时器则清除心跳定时器
      this.close()
      this.timer = setInterval(() => {
        send(HEART_BEAT_TYPE, {date: +new Date()})
      }, this.interval);
    },
    close: function() {
      this.timer && clearInterval(this.timer)
    }
  }

  function createConnect() {
    console.log('建立ws连接')
    //
    const WS_BASE_URL = process.env.REACT_APP_WS_BASE_URL
    // 如果是在重连中，就已经有了定时器尝试重连，不需要本身的超时重连定时器
    if (!reconnectHandle) {
      timeoutHandle && clearTimeout(timeoutHandle)
      timeoutHandle = setTimeout(() => {
        // 最开始的连接就超时，尝试重新连接
        if (timeoutFlag && actReconnectNum < maxReconnectNum) {
          console.log('开始尝试重新连接')
          actReconnectNum++
          createConnect()
        }
      }, timeout);
    }
    const user = JSON.parse(sessionStorage.getItem('user'))
    ws = new WebSocket(WS_BASE_URL + '/' + SYSTEM_CODE + '/' + user.id)
    ws.onopen = e => {
      console.log('onopen', e)
      // 设置属性：没有超时、重连次数归0、清除重连/超时定时器
      timeoutFlag = false
      actReconnectNum = 0
      timeoutHandle && clearTimeout(timeoutHandle)
      reconnectHandle && clearTimeout(reconnectHandle)
      // 开始心跳定时器
      heartBeat.start()
    }

    ws.onmessage = onMessage

    ws.onclose = e => {
      console.log('onclose', e)
      // 关闭心跳发送
      heartBeat.close()
      reconnect() //重连
    }

    ws.onerror = e => {
      console.log('onerror', e)
      reconnect() //重连
    }
  }

  function reconnect() {
    if (reconnectFlag) return
    reconnectFlag = true
    if (actReconnectNum < maxReconnectNum) {
      // 最开始连接上了，但是出错了，重连
      reconnectHandle = setTimeout(() => {
        console.log(`开始重连第${actReconnectNum + 1}次`)
        createConnect()
        actReconnectNum++
        reconnectFlag = false
      }, timeout);
    }
  }

  function onMessage(e) {
    console.log('onmessage', e)
  }

  function send(type, message) {
    ws.send(JSON.stringify(new WSResult(type, message)))
  }

  createConnect()
  return [ ws, send, onMessage ]
}

export default createWS
